package com.stu.moudle.security.config;

import com.stu.moudle.security.UserAuthenticationProvider;
import com.stu.moudle.security.UserPermissionEvaluator;
import com.stu.moudle.security.filter.JWTAuthenticationFilter;
import com.stu.moudle.security.handler.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;

/**
 * 系统安全核心配置
 * 
 * @author ZhangSheng
 *
 */
// 开启方法权限注解
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SysSecurityConfig extends WebSecurityConfigurerAdapter {

	/**
	 * 无权限处理类
	 */
	@Autowired
	private UserAccessDeniedHandler userAccessDeniedHandler;

	/**
	 * 用户未登录处理类
	 */
	@Autowired
	private UserNotLoginHandler userNotLoginHandler;

	/**
	 * 用户登录成功处理类
	 */
	@Autowired
	private UserLoginSuccessHandler userLoginSuccessHandler;

	/**
	 * 用户登录失败处理类
	 */
	@Autowired
	private UserLoginFailureHandler userLoginFailureHandler;

	/**
	 * 用户登出成功处理类
	 */
	@Autowired
	private UserLogoutSuccessHandler userLogoutSuccessHandler;

	/**
	 * 用户登录验证
	 */
	@Autowired
	private UserAuthenticationProvider userAuthenticationProvider;

	/**
	 * 用户权限注解
	 */
	@Autowired
	private UserPermissionEvaluator userPermissionEvaluator;

	/**
	 * 加密方式
	 * 
	 * @return
	 */
	@Bean
	public BCryptPasswordEncoder bCryptPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}

	/**
	 * 注入自定义PermissionEvaluator
	 * 
	 * @return
	 */
	@Bean
	public DefaultWebSecurityExpressionHandler userSecurityExpressionHandler() {
		DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
		handler.setPermissionEvaluator(userPermissionEvaluator);
		return handler;
	}

	/**
	 * 用户登录验证
	 */
	@Override
	protected void configure(AuthenticationManagerBuilder auth) {
		auth.authenticationProvider(userAuthenticationProvider);
	}

	/**
	 * 安全权限配置
	 */
	@Override
	protected void configure(HttpSecurity http) throws Exception {
        // 权限配置
		http.authorizeRequests()
                 // 获取白名单（不进行权限验证）
				.antMatchers(JWTConfig.antMatchers.split(",")).permitAll()
                 // 其他的需要登陆后才能访问
				.anyRequest().authenticated()
                 // 配置未登录处理类
				.and().httpBasic().authenticationEntryPoint(userNotLoginHandler)
                 // 配置登录URL
				.and().formLogin().loginProcessingUrl("/login/submit")
                 // 配置登录成功处理类
				.successHandler(userLoginSuccessHandler)
                 // 配置登录失败处理类
				.failureHandler(userLoginFailureHandler)
                 // 配置登出地址
				.and().logout().logoutUrl("/logout/submit")
                 // 配置用户登出处理类
				.logoutSuccessHandler(userLogoutSuccessHandler)
                 // 配置没有权限处理类
				.and().exceptionHandling().accessDeniedHandler(userAccessDeniedHandler)
                // 开启跨域
				.and().cors()
                // 禁用跨站请求伪造防护
				.and().csrf().disable();
        // 禁用session（使用Token认证）
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // 禁用缓存
		http.headers().cacheControl();
        // 添加JWT过滤器
		http.addFilter(new JWTAuthenticationFilter(authenticationManager()));
	}

}